package club.kingyin.kyblogprouser.controller;



import club.kingyin.commons.clients.FileClient;
import club.kingyin.commons.constant.AuthorizeConstant;
import club.kingyin.commons.entity.file.Quote;
import club.kingyin.commons.entity.user.Message;
import club.kingyin.commons.enums.BlogEnum;
import club.kingyin.commons.request.RequestPage;
import club.kingyin.commons.response.Result;
import club.kingyin.commons.entity.user.User;
import club.kingyin.commons.response.ResultCode;
import club.kingyin.commons.utils.RequestUtils;
import club.kingyin.commons.utils.ResponseUtils;
import club.kingyin.easycache.annotation.EasyCache;
import club.kingyin.kyblogprouser.core.cache.AccessUserHandler;
import club.kingyin.kyblogprouser.core.cache.NicknamesRemoveHandler;
import club.kingyin.kyblogprouser.core.cache.UseridRemoveHandler;
import club.kingyin.kyblogprouser.dao.UserDao;
import club.kingyin.kyblogprouser.entity.UserDetail;
import club.kingyin.kyblogprouser.entity.UserInfo;
import club.kingyin.kyblogprouser.entity.UserPram;
import club.kingyin.kyblogprouser.entity.Users;
import club.kingyin.kyblogprouser.service.FriendService;
import club.kingyin.kyblogprouser.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * (User)表控制层
 *
 * @author makejava
 * @since 2022-01-20 15:04:02
 */
@RestController
@RequestMapping("user")
public class UserController {
    /**
     * 服务对象
     */
    @Resource
    private UserService userService;

    @Resource
    private FriendService friendService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private FileClient fileClient;

    @Resource
    private UserDao userDao;

    /**
     * 分页查询所有数据
     *
     * @return 所有数据
     */
    @PostMapping("/list")
    public Result selectAll(@RequestHeader(AuthorizeConstant.ROLE) String role,
                                        @RequestBody RequestPage<User> params) throws UnsupportedEncodingException {
        switch (Objects.requireNonNull(BlogEnum.deBlogEnum(URLDecoder.decode(role, "UTF8")))) {
            case ADMIN:
            case ROOT:
                return Result.success(userService.selectPage(params.getPage(), params.getO()));
            default: return Result.failR("无操作权限");
        }
    }

//    /**
//     * 通过主键查询单条数据
//     *
//     * @param id 主键
//     * @return 单条数据
//     */
//    @GetMapping("{id}")
//    public Result selectOne(@PathVariable Serializable id) {
//        return Result.success(this.userService.selectById(id));
//    }
//
//    /**
//     * 新增数据
//     *
//     * @param user 实体对象
//     * @return 新增结果
//     */
//    @PostMapping
//    public Result insert(@RequestBody User user) {
//        return Result.success(this.userService.save(user));
//    }
//
//    /**
//     * 修改数据
//     *
//     * @param user 实体对象
//     * @return 修改结果
//     */
//    @PutMapping
//    public Result update(@RequestBody User user) {
//        return Result.success(this.userService.updateById(user));
//    }
//
//    /**
//     * 删除数据
//     *
//     * @param idList 主键结合
//     * @return 删除结果
//     */
//    @DeleteMapping
//    public Result delete(@RequestParam("idList") List<Long> idList) {
//        return Result.success(this.userService.removeByIds(idList));
//    }

    /**
     * 权限验证
     * @param user 用户
     * @return 用户详细信息
     */
    @SneakyThrows
    @PostMapping("/login")
    public Result authentication(@RequestBody User user) {
        User res = userService.equalsAndGet(user);
        if (res == null) {
            return Result.failR("账号或密码错误");
        }
        if (res.getTitled() > System.currentTimeMillis()) {
            return Result.failR("由于您的账号存在违规操作已被封号，将于"+ResponseUtils.stampToTime(res.getTitled())+"解封,申诉请联系QQ：578145931");
        }
        if (res.getTitled() < 0) {
            return Result.failR("您的账号存在违规操作已被封号，申诉请联系QQ：578145931");
        }
        return Result.success(res);
    }

    @PostMapping("/reset")
    public Result reset(@RequestBody User user) {
        try {
            String username = user.getUsername();
            if (userService.selectByUsername(username) == null) {
                return Result.waringR(username+"未注册");
            }
            int code;
            String cs = redisTemplate.opsForValue().get(user.getUsername() + ".code");
            if (cs == null) {
                return Result.waringN("验证码已过期");
            }
            code = Integer.parseInt(cs);
            if (code == user.getId()) {
                boolean res = userService.updatePassword(user);
                if (res) {
                    redisTemplate.delete(user.getUsername() + ".code");
                }
                return res?Result.infoN("重置密码成功"):Result.failR("重置密码失败");
            } else {
                return Result.waringR("验证码错误");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failN("系统异常");
    }

    @EasyCache(handler = {NicknamesRemoveHandler.class})
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        try {
            User current = userService.selectByUsername(user.getUsername());
            if (!current.getStatus().equals(BlogEnum.MAIL)) {
                return Result.infoN("已经注册过了");
            }
            int code;
            String cs = redisTemplate.opsForValue().get(user.getUsername() + ".code");
            if (cs == null) {
                return Result.waringN("验证码已过期");
            }
            code = Integer.parseInt(cs);
            if (code == user.getId()) {
                boolean res = userService.passByUsername(user);
                if (res) {
                    redisTemplate.delete(user.getUsername() + ".code");
                    int count = Integer.parseInt(Objects.requireNonNull(redisTemplate.opsForValue().get("user-count"))) + 1;
                    redisTemplate.opsForValue().set("user-count",String.valueOf(count));
                }
                // 设置初始信息
                Quote video = new Quote();
                video.setId(current.getId());
                video.setPath("http://dev.kingyin.club:9000/cloud/2022225/短视频/1640999005_1645868970708.mp4");
                // 异步
                fileClient.insert(video);
                return res?Result.infoN("注册成功"):Result.failR("注册失败");
            } else {
                return Result.waringR("验证码错误");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failN("验证系统异常");
    }

    // 需要缓存
    @EasyCache(prams = {"userid"},module = "ky-user", time = 4)
    @GetMapping("/info")
    public Result getUserInfo(@RequestHeader(AuthorizeConstant.ID) int userid) {
        User user = userService.selectById(userid);
        UserInfo info = friendService.info(userid);
        info.setUser(user);
        return Result.success(info);
    }

    @EasyCache(prams = {"userid"},module = "ky-user")
    @GetMapping("/info2")
    public Result getUserNicknameAndAvaterById(@RequestParam("userid") int userid) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(User::getAvater,User::getNickname);
        return Result.success(userService.selectById(userid, queryWrapper));
    }

    // 使用handler的注解必须放在第一位，并且不能包含delete属性
    @EasyCache(handler = {NicknamesRemoveHandler.class, UseridRemoveHandler.class})
    @EasyCache(prams = {"userid"}, delete = {"getUserNicknameAndAvaterById","getUserInfo","getUserDetail"}, module = "ky-user")
    @EasyCache(prams = "id", delete = "selectOne", module = "ky-file")
    @PostMapping("/update")
    public Result update(@RequestHeader(AuthorizeConstant.ID) int userid,
            @RequestHeader(AuthorizeConstant.ROLE) String role,
                         @RequestBody User user) throws UnsupportedEncodingException {
        LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate();
        if (user.getPassword() != null && "MANAGE".equals(user.getPassword())) {
            // 系统修改
            // 验证权限
            switch (Objects.requireNonNull(BlogEnum.deBlogEnum(URLDecoder.decode(role, "UTF8")))) {
                case ROOT:
                    // 任意修改
                    userid = user.getId();
                    break;
                case ADMIN:
                    // 不能修改角色
                    user.setRole(null);
                    userid = user.getId();
                    break;
                case USER:
                    // 不能修改titled
                    user.setTitled(null);
                    userid = user.getId();
                    break;
            }
            if (user.getRole() != null) {
                updateWrapper.set(User::getRole, user.getRole());
            }
            if (user.getTitled() != null) {
                updateWrapper.set(User::getTitled, user.getTitled());
            }
        }
        updateWrapper.eq(User::getId, userid).set(User::getNickname, user.getNickname())
                .set(User::getAvater, user.getAvater()).set(User::getSex,user.getSex())
                .set(User::getSlogan, user.getSlogan());

        Quote quote = new Quote();
        quote.setId(userid);
        quote.setPath(user.getUnicode());

        if (userDao.update(null, updateWrapper) > 0) {
            if (fileClient.update(quote).getCode().equals(ResultCode.SUCCESS.val())) {
                // 强制下线
                String token;
                if (user.getTitled() != null && (token = redisTemplate.opsForValue().get(user.getUsername())) != null && user.getTitled() > System.currentTimeMillis()) {
                    Boolean t = redisTemplate.delete(token);
                    Boolean u = redisTemplate.delete(user.getUsername());
                    return t&&u?Result.infoR("更新成功"):Result.failN("更新成功，但是强制下线失败");
                }
                return Result.infoR("更新成功");
            }
            Result.failR("更新失败");
        }
        return Result.failR("更新失败");
    }

//    @EasyCache(module = "ky-user")
    @GetMapping("/names")
    public Result getUserNicknames() {
        return Result.success(userService.selectUserNickname());
    }

    @EasyCache(module = "ky-user")
    @PostMapping("/ids")
    public Result getUsersByIds(@RequestBody Users ids) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(User::getId,ids.getIds()).select(User::getAvater,User::getId,User::getNickname);
        return Result.success(userDao.selectList(queryWrapper));
    }

    // 发送消息
    @EasyCache(prams = {"userid","id"}, module ="ky-user", handler = {AccessUserHandler.class})
    @GetMapping("/detail")
    public Result getUserDetail(@RequestHeader(AuthorizeConstant.ID) int id,
                                @RequestHeader(AuthorizeConstant.NICKNAME) String nickname,
                                @RequestHeader(AuthorizeConstant.AVATAR) String avatar,
                                @RequestParam("userid") int userid) {
        UserDetail detail = new UserDetail();
        User user = userService.selectById(userid);
        if (user == null) {
            return Result.failN("用户不存在");
        }
        user.setStatus(friendService.getStatusByIdAndFriendId(id,userid));
        Result quote = fileClient.getQuoteById(userid);
        String video = (String) ((Map) quote.getData()).get("path");
        Page<User> fans = userService.getFriendsByUserIdAndStatus(new Page<>(1, 4), userid, BlogEnum.BE_CONCERNED);
        Page<User> likes = userService.getFriendsByUserIdAndStatus(new Page<>(1, 4), userid, BlogEnum.CONCERNED);
        detail.setUser(user);
        detail.setFans(fans);
        detail.setLikes(likes);
        detail.setVideo(video);
        return Result.success(detail);
    }
    

    @EasyCache(prams = {"pram.userid","pram.page.current","pram.page.size"}, module = "ky-user")
    @PostMapping("/fans")
    public Result getFansInfo(@RequestBody UserPram pram) {
        return Result.success(userService.getFriendsByUserIdAndStatus(pram.getPage(), pram.getUserid(), BlogEnum.BE_CONCERNED));
    }

    @EasyCache(prams = {"pram.userid","pram.page.current","pram.page.size"}, module = "ky-user")
    @PostMapping("/likes")
    public Result getLikesInfo(@RequestBody UserPram pram) {
        return Result.success(userService.getFriendsByUserIdAndStatus(pram.getPage(), pram.getUserid(), BlogEnum.CONCERNED));
    }

    @GetMapping("/titled")
    public Result getTitledById(@RequestParam int id) {
        return Result.success(userDao.selectById(id).getTitled());
    }

}

